﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using Newtonsoft.Json;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.ServiceComponent.DAC.Service;
using System.Reflection;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Base.Dao;

namespace T.FAS.Runtime.DataModel.Dao
{
    public class EntityObjectELBDao : DaoService<EntityObject>, IEntityObjectDao
    {
        public const string MetaDataID = DataModelConst.EOMetaType;
        public const string MetaDataName = "实体对象";
         
        public override string TableName => "FAS_EntityObject";
        public override string IDColumnName => "ID";
        public override List<string> ExceptColumnName {get;} = 
            DaoUtil.GetExceptionColumn<EntityObject>(
                new List<string>
                {
                    EntityTools.ProjectBranchID,
                });
        private readonly EntityObjectAttributeELBDao _entityObjectAttributeELBDao = new EntityObjectAttributeELBDao();

        public EntityObjectELBDao() : base()
        {
            DBName = "TFAS";
        }

        public override Dictionary<string, PropertyInfo> GetColumns()
        {
            return DaoServiceExtension.GetAllColumns<EntityObject>(base.GetColumns());
        }

        /// <summary>
        /// 获取元数据内容
        /// </summary>
        /// <param name="metaDataId"></param>
        /// <returns></returns>
        public List<EntityObject> GetEntityObjects(Dictionary<string, string> filter)
        {
            var result = new List<EntityObject>();
            if (filter == null)
            {
                return result;
            }
            List<object> objects = base.GetObjectsByFilter("");
            if (objects != null)
            {
                objects.ForEach(obj => result.Add(obj as EntityObject));
            }
            result.ForEach(dao => {
                dao.EntityObjectAttributes = _entityObjectAttributeELBDao.GetEntityObjectAttributes(dao.ID);
                //InitializeEO(dao);   // 递归初始化EO.Attr中的关联EO实例
            });
            return result;
        }

        public EntityObject GetEntityObjectByID(string eoId)
        {
            var EntityObject = base.GetObject(eoId);
            if (EntityObject == null)
                return null;
            EntityObject.EntityObjectAttributes = _entityObjectAttributeELBDao.GetEntityObjectAttributes(eoId);
            //InitializeEO(EntityObject);   // 递归初始化EO.Attr中的关联EO实例
            return EntityObject;
        }

        /// <summary>
        /// 删除EntityObject
        /// </summary>
        /// <param name="EntityObjects"></param>
        public void DeleteEntityObject(string eoId)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    _entityObjectAttributeELBDao.DeleteEntityObjectAttribute(eoId);
                    base.Delete(new List<string> { eoId});
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.EO.DeleteError, e.Message, e);
            }
        }

        public void SaveEntityObject(EntityObject eo)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    base.Add(new List<object> { eo });
                    _entityObjectAttributeELBDao.CreateEntityObjectAttribute(eo.EntityObjectAttributes);
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.EO.CreateError, e.Message, e);
            }
        }

        public void UpdateEntityObject(EntityObject eo)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    DeleteEntityObject(eo.ID);
                    SaveEntityObject(eo);
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.EO.UpdateError, e.Message, e);
            }
        }

        public void DeleteEntityObject(Dictionary<string, string> filter)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    _entityObjectAttributeELBDao.DeleteEntityObjectAttribute(filter["ID"]);
                    base.Delete(new List<string> { filter["ID"] });
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.EO.DeleteError, e.Message, e);
            }
        } 
    }
}
